import {
  FC,
  useEffect,
  useState,
  useRef,
  RefObject,
  CSSProperties,
} from 'react';

import * as echarts from 'echarts/core';
import {
  TitleComponent,
  ToolboxComponent,
  TooltipComponent,
  LegendComponent,
  GridComponent,
} from 'echarts/components';
import { PieChart } from 'echarts/charts';
import { CanvasRenderer } from 'echarts/renderers';

echarts.use([
  TitleComponent,
  ToolboxComponent,
  TooltipComponent,
  LegendComponent,
  PieChart,
  CanvasRenderer,
  GridComponent,
]);

const buildOptions = (
  dataSource: any[],
  colors: string[],
  borderColors: string[] | string = [],
  title: string = '',
  clockwise: boolean = true,
  borderWidth: number,
  radius: [number, number],
  roseType: false | 'radius' | 'area',
  legend: {
    show?: boolean;
    left?: string | number;
    right?: string | number;
    top?: string | number;
    bottom?: string | number;
    textStyle?: CSSProperties;
  },
  center: [string, string],
  titlePosition: {
    top?: number | string;
    left?: number | string;
    right?: number | string;
    bottom?: number | string;
  },
  grid?: {
    top?: number | string;
    left?: number | string;
    right?: number | string;
    bottom?: number | string;
    containLabel?: boolean;
  },
) => {
  return {
    clockwise,
    title: {
      text: title,
      textStyle: {
        color: '#00FFFF',
        fontSize: 20,
        fontWeight: 'normal',
      },
      ...titlePosition,
    },
    legend: {
      ...legend,
    },
    tooltip: {
      trigger: 'item',
      formatter: '{b} : {c} ({d}%)',
    },
    grid: grid,
    series: [
      {
        name: 'pie',
        type: 'pie',
        radius: radius,
        center: center,
        roseType: roseType,
        itemStyle: {
          borderRadius: 1,
        },
        data: buildData(dataSource, colors, borderColors, borderWidth),
      },
    ],
  };
};

const buildData = (
  dataSource: any[],
  colors: string[],
  borderColors: string[] | string,
  borderWidth: number,
) => {
  return dataSource.map((item: any, index: number) => ({
    name: item.name,
    value: item.value,
    itemStyle: {
      borderColor: Array.isArray(borderColors)
        ? borderColors[index]
          ? borderColors[index]
          : colors[index]
        : borderColors,
      color: colors[index],
      borderWidth: borderWidth,
    },
    label: {
      show: true,
      position: 'outside',
      color: colors[index] || 'inherit',
      fontSize: 12,
      overflow: 'break',
      textBorderWidth: 0,
      lineHeight: 20,
    },
    labelLink: {
      show: true,
      lineStyle: {
        color: colors[index],
      },
    },
  }));
};
interface Iprops {
  title?: string;
  width?: number;
  height?: number;
  dataSource: {
    name: string;
    value: number;
  }[];
  colors: string[];
  borderColors?: string[] | string;
  clockwise?: boolean;
  boxStyle?: CSSProperties;
  borderWidth?: number;
  radius?: [number, number];
  roseType?: false | 'radius' | 'area';
  legend?: {
    show?: boolean;
    left?: string | number;
    right?: string | number;
    top?: string | number;
    bottom?: string | number;
    textStyle?: CSSProperties;
    orient?: 'horizontal' | 'vertical';
  };
  center?: [string, string];
  titlePosition?: {
    top?: number | string;
    left?: number | string;
    right?: number | string;
    bottom?: number | string;
  };
  grid?: {
    top?: number | string;
    left?: number | string;
    right?: number | string;
    bottom?: number | string;
    containLabel?: boolean;
  };
}
/**
 *
 * @param {string} title 标题
 * @param {number} width 宽
 * @param {number} height 高
 * @param {Array} dataSource 数据
 * @param {Array} colors 颜色
 * @param {Array} borderColors 边框颜色
 * @param {boolean} clockwise 是否按顺时针排列,默认true
 * @param {string} boxStyle 组件样式
 * @param {number} borderWidth 边框宽度,默认0
 * @param {Array} radius 饼图内外半径
 * @param {any} roseType 饼图展示形式，默认area 面积模式
 * @param {Object} legend 饼图legend
 * @param {Array} center 饼图位置，默认50%,50%,即 中心位置
 */
const Bar: FC<Iprops> = (props) => {
  const {
    width = 330,
    height = 245,
    dataSource,
    colors,
    borderColors,
    title,
    clockwise,
    boxStyle,
    borderWidth = 0,
    radius = [30, 70],
    roseType = 'area',
    legend = {
      show: false,
      orient: 'vertical',
    },
    center = ['50%', '50%'],
    titlePosition = {
      left: 0,
      top: 0,
    },
    grid = {
      top: 0,
      left: 0,
      right: 0,
      bottom: 0,
      containLabel: true,
    },
  } = props;
  const chartRef = useRef() as RefObject<HTMLDivElement>;
  const [chart, setChart] = useState<echarts.ECharts>();

  useEffect(() => {
    const chartDom = chartRef.current as HTMLElement;
    const currentChart = echarts.init(chartDom);
    setChart(currentChart);
  }, []);

  useEffect(() => {
    chart &&
      chart.setOption(
        buildOptions(
          dataSource,
          colors,
          borderColors,
          title,
          clockwise,
          borderWidth,
          radius,
          roseType,
          legend,
          center,
          titlePosition,
          grid,
        ),
      );
  }, [
    chart,
    dataSource,
    colors,
    borderColors,
    title,
    clockwise,
    borderWidth,
    radius,
    roseType,
    legend,
    center,
    titlePosition,
    grid,
  ]);

  return (
    <div
      ref={chartRef}
      style={{
        ...boxStyle,
        width,
        height,
      }}
    ></div>
  );
};
export default Bar;
